package com.google.code.jmarias.client.states;

import com.google.code.jmarias.client.Entity;
import com.google.code.jmarias.client.Globals;
import com.google.code.jmarias.client.GameLocals;
import com.google.code.jmarias.client.components.ImageRenderComponent;
import com.google.code.jmarias.client.components.PrintInfoComponent;
import com.google.code.jmarias.client.tcp.SocketClientInterface;
import com.google.code.jmarias.common.action.*;
import com.google.code.jmarias.client.phases.*;
import com.google.code.jmarias.client.tcp.RemoteServer;
import com.google.code.jmarias.common.AbstractUser;
import com.google.code.jmarias.common.NewPlayer;
import com.google.code.jmarias.common.NewTable;
import com.google.code.jmarias.common.Token;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.state.StateBasedGame;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Herni obrazovka, zachytava prijate akce ze serveru a podle nich spousti jednotlive faze hry
 * 
 * @author bart
 */
public class GameState extends AbstractState {
    private int stateID = -1;
    private static Log log = LogFactory.getLog(GameState.class);
    private NewTable table = new NewTable();
    private GameLocals locals = null;
    private boolean firstLoop = true;
    
    private Queue<AbstractSignedMessage> queue = null;
    private RemoteServer server = null;
    private AbstractSignedMessage action = null;

    private Class currentAction;

    public GameState (int stateID, Globals globals) throws SlickException {
        this.stateID = stateID;
        this.globals = globals;
    }
    

    public int getID() {
        return globals.getGAMESTATE();
    }

    
    public void init(GameContainer gc, StateBasedGame sb) throws SlickException {
        System.out.println("Start");
//        super.loadFonts();

        // Prvni smycka?
        firstLoop = true;


        // Vytvoreni instance stolu
        locals = new GameLocals(globals);


        // Vytvoreni entity stolu
        locals.setBackgroundLayer(new Entity("BackgroundLayer"));
        locals.getBackgroundLayer().setScale(globals.getGlobalScale().x);
        locals.getBackgroundLayer().AddComponent(new ImageRenderComponent(0, new Image(globals.getIMGPATH() + "stul.png")));

        // Vytvoreni informacnich tabuli
        locals.setInfoLayer(new Entity("info"));
        locals.getInfoLayer().setPosition(new Vector2f(0f, 0f));
        locals.getInfoLayer().setScale(1.0f);
        locals.getInfoLayer().AddComponent(new PrintInfoComponent(0, globals, locals));


        // Vytvoreni vybiraciho ramecku
        locals.setFrameEntity(new Entity("pickingFrame"));
        locals.getFrameEntity().setScale(locals.getHandScale());
        locals.getFrameEntity().AddComponent(new ImageRenderComponent(0, new Image(globals.getIMGPATH() + "ramecek.png")));


        // Vytvoreni hracovy ruky
        locals.setHandEntity(new Entity("hand"));
        locals.getHandEntity().setPosition(locals.getHandPosition());
        locals.getHandEntity().setScale(locals.getHandScale());




     
    }

    public void render(GameContainer gc, StateBasedGame sb, Graphics gr) throws SlickException {
        locals.getBackgroundLayer().render(gc, sb, gr);
        locals.getInfoLayer().render(gc, sb,gr);


        if(locals.getCurrentPhase() != null) {
            locals.getCurrentPhase().render(gc,sb,gr);
         } else {
            globals.printText("big", new Vector2f(50f, 400f), Color.white, "Cekam na spojeni..");
//            log.info("Cekam na spojeni se serverem.");
         }

    }

    
    public void update(GameContainer gc, StateBasedGame sb, int delta) throws SlickException {
        Input input = gc.getInput();

        // Prvni smycka po startu nebo restartu hry (pripojeni k serveru aj.)
        if(firstLoop) {
             // Pridani hracu?
             table.addPlayer(new NewPlayer(new AbstractUser("xandre")));
             table.addPlayer(new NewPlayer(new AbstractUser("bot2")));
             table.addPlayer(new NewPlayer(new AbstractUser("bot1")));

             System.out.println("Prvni smycka - update");
             // V pripade, ze client neni pripojen v zadne hre pokusi se ho pripojit.
             SocketClientInterface iface = new SocketClientInterface();
             iface.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(GameState.class.getName()).log(Level.SEVERE, null, ex);
            }

             server = iface.getServer();
             queue = iface.getIncomingActions();

             server.sendAction(new LoginAction("xandre", "12345"));

             firstLoop = false;
        }

        action = queue.poll();
        
        if(action != null) {
            log.debug("Prijata akce: " + action);

            // Vyber  trumfu
            if (action instanceof SignedAction) {
                SignedAction signedAction = (SignedAction) action;
                AbstractAction rawAction = signedAction.getRawAction();
//                if(rawAction instanceof GameAction) {
//                    updateTable(signedAction);
////                    log.debug("Novy stav stolu: \n" + table);
//                }

                if(rawAction instanceof SimpleSystemAction) {
                    server.sendAction(new CreateRoomAction());

                } else if(rawAction instanceof DealSevenCardsAction) {
                    DealSevenCardsAction d = (DealSevenCardsAction) rawAction;
                    if(d.getRecipient().getUsername().equals("xandre")) {
                        System.out.println("Mel bych rozdat sedm karet.");
//                        currentAction = d.getClass();
                        locals.setCurrentPhase(new DealCardsPhase(globals, locals, d.getCards()));
                    } else if(d.getRecipient().getUsername().equals("bot2")) {
                        log.info("Cekam na hrace: " + d.getRecipient().getUsername());
                        locals.setWait(1);
                    } else if(d.getRecipient().getUsername().equals("bot1")) {
                        log.info("Cekam na hrace: " + d.getRecipient().getUsername());
                        locals.setWait(2);
                    }

                } else if(rawAction instanceof DealFiveCardsAction) {
                    DealFiveCardsAction d = (DealFiveCardsAction) rawAction;
                    if(d.getRecipient().getUsername().equals("xandre")) {
                          locals.setCurrentPhase(new DealCardsPhase(globals, locals, d.getCards()));
                    } else if(d.getRecipient().getUsername().equals("bot2")) {
                        log.info("Cekam na hrace: " + d.getRecipient().getUsername());
                        locals.setWait(1);
                    } else if(d.getRecipient().getUsername().equals("bot1")) {
                        log.info("Cekam na hrace: " + d.getRecipient().getUsername());
                        locals.setWait(2);
                    }
                } else if(rawAction instanceof DealFiveHiddenCardsAction) {
                    DealFiveHiddenCardsAction d = (DealFiveHiddenCardsAction) rawAction;
                    if(d.getRecipient().getUsername().equals("xandre")) {
                          locals.setCurrentPhase(new DealCardsPhase(globals, locals, d.getCards()));
                    } else if(d.getRecipient().getUsername().equals("bot2")) {
                        log.info("Cekam na hrace: " + d.getRecipient().getUsername());
                        locals.setWait(1);
                    } else if(d.getRecipient().getUsername().equals("bot1")) {
                        log.info("Cekam na hrace: " + d.getRecipient().getUsername());
                        locals.setWait(2);
                    }                    
                } else if(rawAction instanceof UnhideFiveCardsAction) {
                    UnhideFiveCardsAction d = (UnhideFiveCardsAction) rawAction;
                    if(d.getRecipient().getUsername().equals("xandre")) {
                          locals.setCurrentPhase(new DealCardsPhase(globals, locals, d.getCards()));
                    } else if(d.getRecipient().getUsername().equals("bot2")) {
                        log.info("Cekam na hrace: " + d.getRecipient().getUsername());
                        locals.setWait(1);
                    } else if(d.getRecipient().getUsername().equals("bot1")) {
                        log.info("Cekam na hrace: " + d.getRecipient().getUsername());
                        locals.setWait(2);
                    }
                    
                }


            } else if (action instanceof Token) {
                Token token = (Token) action;
                if(token.getPlayingNow().getUsername().equals("xandre")) {
                    log.debug("Ceka se na me.");
                    log.debug("Povolene akce: " + token.getAllowedActions());
                    locals.setWait(0);
                    if(token.getAllowedActions().contains(PickedTrumpAction.class)) {
                        log.debug("Prechazim do faze vyberu trumfu");
                        locals.setCurrentPhase(new PickTrumpPhase(server, globals, locals, token.getAllowedActions()));
                    } else if(token.getAllowedActions().contains(PickCardFromPeopleAction.class)) {
                        log.debug("Prechazim do faze voleni z lidu.");
                        locals.setCurrentPhase(new ChooseFromPeoplePhase(server, globals, locals));
                    } else if(token.getAllowedActions().contains(DropTalonAction.class)) {
                        log.debug("Prechazim do faze odhozeni talonu.");
                        locals.setCurrentPhase(new DropTalonPhase(server, globals, locals));
                    } else {
                        log.debug("Prechazim do ptaci faze.");
                        locals.setCurrentPhase(new AskForChoicePhase(server, globals, locals, token.getAllowedActions()));
                    }



//                    if(currentAction.equals(DealSevenCardsAction.class)) {
//                        System.out.println("Vybiram trumf");
//                        locals.setCurrentPhase(new PickTrumpPhase(server, globals, locals, token.getAllowedActions()));
//                    } else if(currentAction.equals(DealFiveCardsAction.class)) {
//                        locals.setCurrentPhase(new DropTalonPhase(server, globals, locals));
//                        System.out.println("Vybiram talon");
//                    }
                }
            }
        }
               



//            } else if(action instanceof Token) {
//                Token token = (Token) action;
//                if(token.getPlayingNow().getUsername().equals("xandre")) {
//                    log.debug("Na rade je hrac xandre");
////                    if(action instanceof DealSevenCardsAction)
////                        locals.setCurrentPhase(new PickTrumpPhase(d,server, globals, locals));
//
//
////                    for(int i = 0; i < token.getAllowedActions().size(); i++) {
////                        allowedActionsText.add(token.getAllowedActions().toArray()[i].toString());
////                    }
//
//                    if(currentAction.equals("DealSevenCardsAction")) {
//                        log.info("Mel bych vybrat trumf");
//                        locals.setCurrentPhase(new PickTrumpPhase(server, globals, locals, token.getAllowedActions()));
//                    }
//
//
//                }
//            } else if(action instanceof DealSevenCardsAction) {
//                  DealSevenCardsAction d = (DealSevenCardsAction) action;
//                  currentAction = "DealSevenCardsAction";
//
//                  if(d.getCards()[0] != null) {
//                      log.debug("Jsem volici hrac! Vytvarim karty ...");
//
//                      log.debug(" OK ");
//                      log.debug("Spoustim fazi rozdani karet");
//
//                      locals.setCurrentPhase(new DealCardsPhase(globals, locals, d.getCards()));
//
//                  }
//
////                DealSevenCardsAction d = (DealSevenCardsAction) action;
////                locals.setCurrentPhase(new PickTrumpPhase(d,server, globals, locals));
////            allowedActionsText.clear();
//            // @TODO tohle jsem musel zakomentovat, protoze getAllowedActions se prenasi uz jinak,
//            // takze to asi prestane fungovat
////            for(int i = 0; i < d.getAllowedActions().size(); i++) {
////                allowedActionsText.add(d.getAllowedActions().get(i).toString());
////            }
//
//            // Voleni z lidu
//            } else if(action instanceof ChooseFromPeopleAction) {
//                ChooseFromPeopleAction d = (ChooseFromPeopleAction) action;
////                locals.setCurrentPhase(new ChooseFromPeoplePhase(d,server, globals, locals));
//
//            } else if(action instanceof DealFiveCardsAction) {
//                DealFiveCardsAction d = (DealFiveCardsAction) action;
//                if(d.getCards()[0].getValue() == null) {
//                    log.info("Nekomu rozdavam pet karet.");
//                }
////                locals.setCurrentPhase(new DropTalonPhase(d, server, globals, locals));
//
//            } else if(action instanceof AskForChoiceAction) {
//                AskForChoiceAction d = (AskForChoiceAction) action;
////                locals.setCurrentPhase(new ChooseGamePhase(d,server, globals, locals));
//
//            } else if(action instanceof PickCardFromPeopleAction) {
//                PickCardFromPeopleAction d = (PickCardFromPeopleAction) action;
////                locals.setTrumpCard(d.getPickedCard());
//            }
//        }




        if(locals.getCurrentPhase() != null)
            locals.getCurrentPhase().update(gc,null,delta);


        // Obsluha klavesnice
        if(input.isKeyPressed(Input.KEY_ESCAPE)) {
            MainMenuState.setRestarting(false);
            sb.enterState(globals.getMAINMENUSTATE());
        } else if(input.isKeyPressed(Input.KEY_0)) {
            locals.setCurrentPhase(null);
        } else if(input.isKeyPressed(Input.KEY_1)) {
            // Spusteni ChooseFromPeople faze

            locals.setCurrentPhase(null);
            server.sendAction(new ChooseFromPeopleAction());
        } else if(input.isKeyPressed(Input.KEY_2)) {
        }


        /* Vsem ostatnim tlacitku vycisti prirazene akce */
        super.nullControls(gc);
    }


    public void updateTable(SignedAction action) {
        action.updateTable(table);
    }
}
